A receive-any thread is a thread of execution in a server process that handles both requests for new connections and incoming remote procedure call (RPC) requests on (one or more) existing connections, if any. The receive-any thread responds to a new connection request by posting an accept, and to an RPC data request by posting a receive. Receive-any threads accomplish this dual-functionality using a Windows.RTM. Sockets API (WinSock) call such as selects( ) to block, listening for new connection requests and activity on existing connections. Other environments use similar APIs. Since RPC servers typically listen on more than one protocol (e.g., TCP, SPX or ADSP) at any given time, one receive-any thread is provided to deal with each protocol.
However, because receive-any threads multiplex between requests for new connections and receiving RPC data, perform parameter validation and do extra data copying (buffering), they are relatively slow. More particularly, when receiving data via a receive-any thread, the cost of the select and the extra copying cost of transferring data from the transport buffers to the RPC runtime add substantial runtime overhead. As a result, another type of thread known as a receive-direct thread may be used for an existing data connection.
A receive-direct thread is a dedicated thread which receives RPC requests on a specific connection and dispatches those requests. A receive-direct thread pre-posts a receive on the connection to avoid the data copying and the overhead associated with select( ), i.e., using the WinSock recv( ) API, a receive-direct thread receives data into application buffers as the data arrives. Receive-direct threads thus have less runtime overhead and provide better performance when handling data than do receive-any threads. Indeed, in certain instances, the use of a receive-direct thread provides at least a twenty percent performance improvement over a receive-any thread.
However, each receive-direct thread has costs associated therewith including an increased memory size and footprint. With the above scheme of making existing data connections receive-direct connections, many receive-direct threads, up to some predetermined quota, may be allocated in memory. If a connection is idle or mostly idle, the receive-direct thread associated therewith is also idle and system resources are wasted. Moreover, a receive-direct thread may not be available for a newer, highly active connection because other for a newer, highly active connections because other connections, including idle connections, have used up the quota of receive-direct threads. The highly active connection instead has to remain receive-any, and thus suffers from the reduced performance associated with receive-any data handling.